/*
 * Developer : Jack Matthews
 * Email: developer@droidprofessor.com
 * 
 * Copyright (C) 2010 http://droidprofessor.com
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.droidprofessor.android.library.phonelicenses;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.droidprofessor.android.licensegenerator.client.AndroidClientLicenseImpl;

import android.content.Context;
import android.util.Log;

/**
 * Holds Application XML data when it is retrieved from the server
 * 
 * @author Jack Matthews
 *
 */
enum ApplicationDataCache {
	INSTANCE;
	
	private final List<PaymentMethod> paymentMethods = new ArrayList<PaymentMethod>();
	private String applicationName = null;
	private String description = null;
	private String supportEmail = null;
	private String phoneProductsUrl = null;
	private String merchantName = null;
	private String licenseAgreement = null;
	private String refundPolicy = null;
	private String baseUrl = null;
	
	static ApplicationDataCache getInstance() {
		return ApplicationDataCache.INSTANCE;
	}
	
	/**
	 * Reset the application to a null state
	 */
	void reset() {
		this.applicationName = null;
		this.description = null;
		this.supportEmail = null;
		this.phoneProductsUrl = null;
		this.merchantName = null;
		this.licenseAgreement = null;
		this.refundPolicy = null;
		this.paymentMethods.clear();
	}
	
	/**
	 * Get a Payment Method via its reference name
	 * 
	 * @param refName
	 * @return the PaymentMethod if the reference if found and enabled or null otherwise
	 */
	PaymentMethod getPaymentMethodByReferenceName(String refName) {
		for(PaymentMethod pm : this.paymentMethods) {
			if(pm.getRefName().equals(refName) && pm.isEnabled())
				return pm;
		}
		
		return null;
	}
	
	
	
	/**
	 * Get all payment methods
	 * 
	 * @return a copy of the enabled payment methods available
	 */
	List<PaymentMethod> getEnabledPaymentMethods() {
		List<PaymentMethod> enabledPaymentMethods = new ArrayList<PaymentMethod>();
		for(PaymentMethod pm : this.paymentMethods ) {
			if(pm.isEnabled()) {
				enabledPaymentMethods.add(pm);
			}
		}
		
		return enabledPaymentMethods;
	}



	/**
	 * Add a payment method
	 * 
	 * @param paymentMethod
	 */
	void addPaymentMethod(PaymentMethod paymentMethod) {
		this.paymentMethods.add(paymentMethod);
	}


	String getBaseUrl() {
		return baseUrl;
	}

	void setBaseUrl(String baseUrl) {
		this.baseUrl = baseUrl;
	}

	String getApplicationName() {
		return applicationName;
	}




	void setApplicationName(String applicationName) {
		this.applicationName = applicationName;
	}




	String getDescription() {
		return description;
	}




	void setDescription(String description) {
		this.description = description;
	}




	String getSupportEmail() {
		return supportEmail;
	}




	void setSupportEmail(String supportEmail) {
		this.supportEmail = supportEmail;
	}




	 String getPhoneProductsUrl() {
		return phoneProductsUrl;
	}




	 void setPhoneProductsUrl(String phoneProductsUrl) {
		this.phoneProductsUrl = phoneProductsUrl;
	}




	 String getMerchantName() {
		return merchantName;
	}




	 void setMerchantName(String merchantName) {
		this.merchantName = merchantName;
	}




	 String getLicenseAgreement() {
		return licenseAgreement;
	}




	 void setLicenseAgreement(String licenseAgreement) {
		this.licenseAgreement = licenseAgreement;
	}




	 String getRefundPolicy() {
		return refundPolicy;
	}




	 void setRefundPolicy(String refundPolicy) {
		this.refundPolicy = refundPolicy;
	}




	/**
	 * A payment method
	 * 
	 * @author Jack Matthews
	 *
	 */
	 static class PaymentMethod {
		private static final String TAG = "PaymentMethod";
		private static final String INTEGRATED = "integrated";
		private static final String HTML = "html";
		
		//Integration Codes for Payment Methods
		static final String INTEGRATION_CODE_PAYPAL = "paypal";
		static final String INTEGRATION_CODE_ANDROIDMARKET = "androidmarket";
		
		//Reference Names
		public final static String REFNAME_PAYPAL_INTEGRATED = "paypal_integrated";
		public final static String REFNAME_PAYPAL_HTML = "paypal_html";
		public final static String REFNAME_ANDROIDMARKET_INTEGRATED = "androidmarket_integrated";
		public final static String REFNAME_ONEBIP_HTML = "onebip_html";
		private final static String REFNAME_GOOGLECHECKOUT_HTML = "googlecheckout_html";

		private boolean enabled = false;
		private String refName;
		private String name;
		private String description;
		private String price;
		private String currency;
		private String buttonInformation;
		private String buttonType;
		private final Map<String, String> extras = new HashMap<String, String>();
		
		/**
		 * These filters will replace existing code int he 
		 * HTML button.
		 * 
		 * @return filtered button code
		 * 
		 */
		private String applyHtmlFilters(Context cnx, String buttonCode) {
			buttonCode = buttonCode.replaceAll(
					"\\{IDUSERNAME\\}", 
					AndroidClientLicenseImpl.getInstance().getApplicationId()+":"+PreferencesHelper.getUsername(cnx)
					);
//			buttonCode = buttonCode.replaceAll(
//					"\\{EMAIL\\}", 
//					PreferencesHelper.getEmail(cnx)
//					);
			buttonCode = buttonCode.replaceAll(
					"\\{NAME\\}", 
					PreferencesHelper.getName(cnx)
					);
			
			return buttonCode;
		}



		 String getRefName() {
			return refName;
		}

		 void setRefName(String refName) {
			this.refName = refName;
		}

		 String getDescription() {
			return description;
		}

		 void setDescription(String description) {
			this.description = description;
		}

		 boolean isEnabled() {
			return enabled;
		}

		 void setEnabled(boolean enabled) {
			this.enabled = enabled;
		}

		 String getName() {
			return name;
		}

		 void setName(String name) {
			this.name = name;
		}

		 String getPrice() {
			return price;
		}

		 void setPrice(String price) {
			this.price = price;
		}

		 String getCurrency() {
			return currency;
		}

		 void setCurrency(String currency) {
			this.currency = currency;
		}

		
		/**
		 * Get the Html button
		 * 
		 * @param cnx
		 * @return the filtered html button code
		 * @throws IllegalAccessException if this button is not of type html
		 */
		public String getHtmlButton(Context cnx) throws IllegalAccessException {
			if(this.buttonType.equals(HTML)) {
				return applyHtmlFilters(cnx, buttonInformation);
			} else {
				Log.e(TAG, "This payment method is not of type HTML");
				throw new IllegalAccessException("This payment method is not of type HTML");
			}
		}
		
		
		/**
		 * Get the button integration code
		 * 
		 * @return the button integration code, used to access an appropriate integration class
		 * @throws IllegalAccessException if the button is not of type INTEGRATED
		 */
		public String getButtonIntegrationCode() throws IllegalAccessException {
			if(buttonType.equals(INTEGRATED))
				return this.buttonInformation;
			else {
				Log.e(TAG, "This payment method is not of type INTEGRATED");
				throw new IllegalAccessException("This payment methods is not of type INTEGRATED");
			}
		}

		public void setButtonInformation(String buttonInformation) {
			this.buttonInformation = buttonInformation;
		}

		public String getButtonType() {
			return buttonType;
		}

		public void setButtonType(String buttonType) {
			this.buttonType = buttonType;
		}

		public Map<String, String> getExtras() {
			return new HashMap<String, String>(extras);
		}

		public void addExtra(String key, String value) {
			this.extras.put(key, value);
		}
		
		public String getExtra(String key) {
			return this.extras.get(key);
		}

		public int getImageResource() {
			if(refName.equals(REFNAME_ANDROIDMARKET_INTEGRATED))
				return R.drawable.com_phonelicenses_androidmarket_logo;
			else if(refName.equals(REFNAME_PAYPAL_HTML))
				return R.drawable.com_phonelicenses_paypal_logo;
			else if(refName.equals(REFNAME_GOOGLECHECKOUT_HTML))
				return R.drawable.com_phonelicenses_googlecheckout_logo;
			else if(refName.equals(REFNAME_PAYPAL_INTEGRATED))
				return R.drawable.com_phonelicenses_paypal_logo; 
			else if(refName.equals(REFNAME_ONEBIP_HTML))
				return R.drawable.com_phonelicenses_onebip_logo;
			else
				return android.R.drawable.ic_menu_help;
		}
		
		
//		/**
//		 * 
//		 * @return the custom string that will be passed to the PayPal IPN
//		 */
//		private String generateApplicationIdUsernameString() {
//			//Create the custom string for use by the PayPal IPN
//			String appId = AndroidClientLicenseImpl.getInstance().getApplicationId();
//			String username = PreferencesHelper.getUsername(getApplicationContext());
//			
//			//Some validation just in case something weird happened
//			if(username == "" || appId == "")
//				throw new IllegalArgumentException("Username: "+username+" AppID: "+appId+" must both have values other then null");
//			
//			String custom = appId+":"+username; //The string format is id:username
//			
//			if(Logging.DEBUG) Log.d(TAG, "Custom String: "+custom);
//			return custom; 
//		}
	}



	/**
	 * Has the data already been downloaded
	 * 
	 * @return boolean
	 */
	 boolean isPopulated() {
		return applicationName != null;
	}
}
